using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FernUniHagen.CompilerExtension.DataStructures;
using FernUniHagen.CompilerExtension.Interfaces;
using Roslyn.Compilers.Common;
using Roslyn.Compilers.CSharp;

namespace FernUniHagen.CompilerExtension.Adaptor
{
    public class FieldDeclarationAdapter : DeclarationBase, IDeclaration<CommonSyntaxNode>
    {
        FieldDeclarationSyntax _fieldDeclaration;




        public FieldDeclarationAdapter(ISemanticModel model, FieldDeclarationSyntax node )
        {
            this.SemanticModel = model;
            _fieldDeclaration = node;
            Initialize();

        }

        /// <summary>
        /// Returns the name of the variable
        /// TODO: Multiple Variable Names not supported e.g.: string a,b
        /// </summary>
        /// <returns></returns>
        public override string GetName()
        {
            return _fieldDeclaration.Declaration.Variables.First().ToString();
        }

        public override TypeSyntax GetTypeSyntax()
        {
            return _fieldDeclaration.Declaration.Type;
        }

        public override SyntaxList<AttributeListSyntax> GetAttributes()
        {
            return _fieldDeclaration.AttributeLists;
        }

        public override StatementReplacement<CommonSyntaxNode> ConvertToMutiplicity(string newVariableName)
        {

            var newFieldDeclaration = _fieldDeclaration;

            //Rename the field in any case (even if option)
            foreach (var declarationSyntax in _fieldDeclaration.Declaration.Variables)
            {
                var decleratorSyntaxes = new SeparatedSyntaxList<VariableDeclaratorSyntax>();
                var identifier = Syntax.ParseToken(newVariableName);
                var declaratorSyntax = declarationSyntax.WithIdentifier(identifier);
                decleratorSyntaxes = decleratorSyntaxes.Add(declaratorSyntax);
                var variableDecleration = newFieldDeclaration.Declaration.WithVariables(decleratorSyntaxes);
                newFieldDeclaration = newFieldDeclaration.WithDeclaration(variableDecleration);
            }

            //in case of any field adjust the type and create an initializer
            if (MultiplicityType == AttributeType.Any)
            {
                //Convert the decleration site
                VariableDeclarationSyntax newDeclaration = newFieldDeclaration.Declaration.WithType(GenericName);
                newFieldDeclaration = newFieldDeclaration.WithDeclaration(newDeclaration);
              //  VariableDeclarationSyntax variableDecleration2 = newFieldDeclaration.Declaration.WithVariables(new SeparatedSyntaxList<VariableDeclaratorSyntax>());
              //  newFieldDeclaration = newFieldDeclaration.WithDeclaration(variableDecleration2);
                SeparatedSyntaxList<VariableDeclaratorSyntax> decleratorSyntaxes = new SeparatedSyntaxList<VariableDeclaratorSyntax>();
                //Build up the initializer site
                foreach (var declerationSyntax in newFieldDeclaration.Declaration.Variables)
                {
                    EqualsValueClauseSyntax oldInitializer = declerationSyntax.Initializer;
                    if (oldInitializer != null) continue;
                    //TODO: public string _email, test; doesnot work
                    ExpressionSyntax initializerExpression = Syntax.ParseExpression(string.Format(" new {0}()", GenericName.ToString()));
                    EqualsValueClauseSyntax newInitializer = Syntax.EqualsValueClause(initializerExpression);
                    var decleratorSyntax = declerationSyntax.WithInitializer(newInitializer);
                    decleratorSyntaxes = decleratorSyntaxes.Add(decleratorSyntax);

                }
                VariableDeclarationSyntax variableDecleration = newFieldDeclaration.Declaration.WithVariables(decleratorSyntaxes);
                newFieldDeclaration = newFieldDeclaration.WithDeclaration(variableDecleration);
              //  newField = newField.WithAttributeLists(null);
                return new StatementReplacement<CommonSyntaxNode>(_fieldDeclaration, newFieldDeclaration);
            }
            return new StatementReplacement<CommonSyntaxNode>(_fieldDeclaration, newFieldDeclaration);
        }
    }
}
